package db_sports

import (
	"errors"
	"fmt"
	"github.com/jinzhu/copier"
	global2 "longmen/server/config/global"
	_const "longmen/server/pkg/common/helper/const"
	time2 "longmen/server/pkg/common/helper/timehelper"
	"longmen/server/pkg/common/helper/util"
	"longmen/server/pkg/db/mysql"
	"longmen/server/pkg/db/mysql/models/models_live"
	db_main2 "longmen/server/pkg/db/mysql/models/models_main"
	"longmen/server/pkg/db/mysql/models/models_sports"
	protobuf2 "longmen/server/pkg/protobuf"
	"strconv"
	"strings"
	"time"

	"github.com/spf13/cast"

	// _ "github.com/jinzhu/copier"

	"longmen/server/pkg/common/api_models"

	"gorm.io/gorm"
)

type Matches struct {
	model models_sports.Matches
}

// GetMatchPlayUrls 获取赛事列表分页
func (m Matches) GetMatchPlayUrls(args map[string]interface{}, order string, page, size int) ([]models_sports.Matches, error) {
	records := make([]models_sports.Matches, 0)
	table := mysql.GetRTable(m.model)
	mysql.Condition(table, args, "", order, page, size)
	err := table.Find(&records).Error
	if err != nil {
		return nil, err
	}
	return records, nil
}

// GetMatchDetail 获取赛事详情
func (m Matches) GetMatchDetail(args map[string]interface{}) (models_sports.Matches, error) {
	table := mysql.GetRTable(m.model)
	mysql.Condition(table, args, "", "", 0, 1)
	err := table.Find(&m.model).Error
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		return m.model, err
	}
	return m.model, nil
}

func (m Matches) GetMatchesRecords(args map[string]interface{}, order string, page, size int) ([]models_sports.Matches, error) {
	matchRecords := make([]models_sports.Matches, 0)

	table := mysql.GetRTable(m.model)
	mysql.Condition(table, args, "", order, page, size)
	err := table.Find(&matchRecords).Error
	if err != nil {
		return matchRecords, err
	}
	return matchRecords, nil
}

func (m Matches) GetMatchesUnionAll(args map[string]interface{}, order string, size int) ([]models_sports.Matches, error) {
	matchRecords := make([]models_sports.Matches, 0)

	const QuerySql = `
SELECT * FROM db_matches WHERE (sport_id = ?) AND match_status in (?) AND match_time  >  ?  AND match_time  <  ? 
UNION ALL 
SELECT * FROM db_matches WHERE (sport_id = ?) AND match_status in (?) AND match_time  >  ?  AND match_time  <  ? 
ORDER BY  %s  LIMIT ?
`
	sql := fmt.Sprintf(QuerySql, order)
	m2 := args["match_time"].(map[string]interface{})
	scan := global2.GetR().Raw(sql,
		util.FootBall, util.SportStatus[args["match_status"].(int)][util.FootBall], m2[">"], m2["<"],
		util.BasketBall, util.SportStatus[args["match_status"].(int)][util.BasketBall], m2[">"], m2["<"],
		size,
	).Scan(&matchRecords)
	if scan.Error != nil {
		return matchRecords, scan.Error
	}
	return matchRecords, nil
}

// GetLiveRecords 获取直播记录
func GetLiveRecords(matchIds []int) map[int][]models_sports.SuggestLive {
	model := models_live.Live{}
	records := make([]models_sports.SuggestLive, 0)
	recordMap := make(map[int][]models_sports.SuggestLive)

	err := global2.GetR().Model(&model).
		Where("matchid", matchIds).
		Joins("left join db_user u on live.anchorid=u.id").
		Select("anchorid, matchid, liveid, u.Avatar as logo,u.nick_name as nickname").
		Group("anchorid").
		Having(" COUNT(live.anchorid) < 5 ").
		Find(&records).Error

	if err != nil {
		global2.Log.Error("error get match : ", err)
		return recordMap
	}

	for _, record := range records {
		recordMap[record.Id] = append(recordMap[record.Id], record)
	}

	return recordMap
}

// 获取赛事临时表数据
func GetTempMatches(param map[string]interface{}, order string, page, size int) ([]*protobuf2.GetHotMatchCards4Crawler, error) {
	matchTemps := make([]*models_sports.MatchTempSchedule, 0)
	table := mysql.GetSportsTable(&models_sports.MatchTempSchedule{})
	mysql.Condition(table, param, "", order, page, size)
	err := table.Find(&matchTemps).Error
	if err != nil {
		return nil, err
	}
	var resp []*protobuf2.GetHotMatchCards4Crawler
	for _, v := range matchTemps {
		matchesSuggest := &protobuf2.GetHotMatchCards4Crawler{
			Away:              v.Away,
			AwayScore:         v.AwayScore,
			AwayLogo:          v.AwayLogo,
			Comp:              v.Comp,
			Home:              v.Home,
			HomeScore:         v.HomeScore,
			HomeLogo:          v.HomeLogo,
			CompLogo:          v.CompLogo,
			MatchDetailStatus: v.MatchDetailStatus,
			MatchTime:         v.MatchTime,
			TimePlayed:        v.TimePlayed,
		}
		resp = append(resp, matchesSuggest)
	}
	return resp, nil
}

func GetRecommendMatches4Crawler(startTime, endTime int64, sportId uint32, compareDateAndNow int) ([]*models_sports.MatchTempSchedule, error) {
	matchTemps := make([]*models_sports.MatchTempSchedule, 0)
	table := mysql.GetSportsTable(&models_sports.MatchTempSchedule{})
	addStr := " and flag=2"
	if sportId > 0 {
		addStr = fmt.Sprintf("and sport_id=%d", sportId)
	}
	sql := fmt.Sprintf("SELECT * FROM db_matches_schedule WHERE match_time >=%d AND match_time <= %d and match_status=2 %s ORDER BY match_time ASC LIMIT 10", startTime, endTime, addStr)
	if compareDateAndNow == -1 {
		sql = fmt.Sprintf("SELECT * FROM db_matches_schedule WHERE match_time >= %d AND match_time <= %d and match_status=3 %s ORDER BY match_time desc LIMIT 10", startTime, endTime, addStr)
	} else if compareDateAndNow == 0 {
		sql = fmt.Sprintf("select * from (SELECT * FROM db_matches_schedule WHERE match_time >= %d AND match_time <= %d and match_status=1 %s ORDER BY match_time ASC LIMIT 10)tb1  union select * from (SELECT * FROM db_matches_schedule WHERE match_time >= %d AND match_time <= %d and match_status=2 %s ORDER BY match_time ASC LIMIT 10)tb2 union select *from(SELECT * FROM db_matches_schedule WHERE match_time >= %d AND match_time <= %d and match_status=3 %s ORDER BY match_time ASC LIMIT 10)tb3", startTime, endTime, addStr, startTime, endTime, addStr, startTime, endTime, addStr)
	}
	err := table.Raw(sql).Find(&matchTemps).Error
	if err != nil {
		return nil, err
	}
	return matchTemps, err
}

func GetMatch4Crawler(param map[string]interface{}, isLive uint32, page, size int) ([]*models_sports.MatchTempSchedule, int64, int64, int64, error) {
	fName := "GetMatch4Crawler"
	var count int64
	var soccerCount int64
	var basketballCount int64
	matchTemps := make([]*models_sports.MatchTempSchedule, 0)
	db1 := mysql.GetSportsTable(&models_sports.MatchTempSchedule{})
	if isLive > 0 {
		db1.Joins("inner join(select DISTINCT matchid match_id from live.db_live) tb1 on models_sports.db_matches_schedule.match_id=tb1.match_id ")
	}
	mysql.Condition(db1, param, "", "match_status ASC", page, size)
	err := db1.Find(&matchTemps).Error
	if err != nil {
		return nil, 0, 0, 0, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	db2 := mysql.GetSportsTable(&models_sports.MatchTempSchedule{})
	if isLive > 0 {
		db2.Joins("inner join(select DISTINCT matchid match_id from live.db_live) tb1 on models_sports.db_matches_schedule.match_id=tb1.match_id ")
	}
	mysql.Condition(db2, param, "", "", 0, 0)
	err = db2.Count(&count).Error
	if err != nil {
		return nil, 0, 0, 0, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	delete(param, "comp")
	delete(param, "flag")
	delete(param, "match_status")
	db3 := mysql.GetSportsTable(&models_sports.MatchTempSchedule{})
	param["sport_id"] = 1
	mysql.Condition(db3, param, "", "", 0, 0)
	err = db3.Count(&soccerCount).Error
	if err != nil {
		return nil, 0, 0, 0, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	db4 := mysql.GetSportsTable(&models_sports.MatchTempSchedule{})
	param["sport_id"] = 2
	mysql.Condition(db4, param, "", "", 0, 0)
	err = db4.Count(&basketballCount).Error
	if err != nil {
		return nil, 0, 0, 0, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return matchTemps, count, soccerCount, basketballCount, nil
}

//func GetCountOfMatch4Crawler() (int64, error) {
//	fName := "GetCountOfMatch4Crawler"
//	var count int64
//	table := getRTable(&models.MatchTempSchedule{})
//	err := table.Count(&count).Error
//	if err != nil {
//		return 0, fmt.Errorf("%s%s", common.Convert(fName), err.Error())
//	}
//	return count, nil
//}

/**
* @Author:admin
* @Description: 排序规则 是先按时间排序取前 30条记录，在30条记录中 再按 重要赛事 ->进行中 -> 未开赛 sort 字段排序
* @Param :
* @Return :
* @Date: 15:22 2022/6/22
 */
func GetHotMatchCards4Crawler(startTime, endTime int64) ([]*models_sports.MatchTempSchedule, error) {
	fName := "GetHotMatchCards4Crawler"
	table := &models_sports.MatchTempSchedule{}
	resp := make([]*models_sports.MatchTempSchedule, 0)
	global2.Log.Debugf("raceBreed val:%v", global2.Config.GetInt("raceBreed"))
	if global2.Config.GetInt("raceBreed") == 1 {
		endTime += 86400 * 2
	}
	err := mysql.GetSportsTable(table).
		Raw("select tb1.*,CASE flag WHEN 2 then 100 else case match_status when 1 then 90 when 2 then 80 else 70 end END sort from "+
			"(select * from db_matches_schedule where match_time>=? and match_time<=? and match_status not in(3,4) order by match_time asc limit 30)tb1 order by sort desc,match_time asc", startTime, endTime).
		Find(&resp).
		Error
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return resp, nil
}

/**
* @Author:admin
* @Description:查询联赛标签
* @Param :
* @Return :
* @Date: 18:52 2022/6/21
 */
func GetCompetation4Crawler(sportType uint8) (compList []*protobuf2.GetCompetation4CrawlerItem, err error) {
	//copier.Copy()
	sql := "select label  comp,label_pic from db_comp_label"
	if sportType > 0 {
		sql = fmt.Sprintf("%s where sport_id=? order by serial", sql)
		err = global2.Sport().Raw(sql, sportType).Find(&compList).Error
	} else {
		sql = fmt.Sprintf("%s  order by serial", sql)
		err = global2.Sport().Raw(sql).Find(&compList).Error
	}

	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert2(), err.Error())
	}
	return compList, nil
}

/**
* @Author:admin
* @Description: 查询出所有列表标签
* @Param :
* @Return :
* @Date: 13:14 2022/6/22
 */
func GetCompLabelList() ([]*models_sports.CompLabel, error) {
	o := make([]*models_sports.CompLabel, 0)
	table := mysql.GetSportsTable(&models_sports.CompLabel{})
	err := table.Find(&o).Error
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert2(), err.Error())
	}
	return o, nil
}

func GetMatch4CrawlerByParam(param map[string]interface{}, group, order string, page, size int) ([]*models_sports.MatchTempSchedule, error) {
	o := make([]*models_sports.MatchTempSchedule, 0)
	table := mysql.GetSportsTable(&models_sports.MatchTempSchedule{})
	err := mysql.Condition(table, param, group, order, page, size).Find(&o).Error
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert2(), err.Error())
	}
	return o, nil
}

func GetAnchorReservation(matchIds []int) ([]*api_models.GetAnchorReservation, error) {
	fName := "GetAnchorReservation"
	anchorBaseList := make([]*api_models.GetAnchorReservation, 0)
	db := global2.GetR()
	var err = db.
		Raw(fmt.Sprintf(`SELECT
								o.*
								FROM
									(
									SELECT
										r.match_id AS match_id,
										r.user_id AS anchor_id,
										u.avatar AS anchor_avatar 
									FROM
										db_user_reservation r
										LEFT JOIN db_user u ON u.id = r.user_id 
									WHERE
									r.match_id in (%s)
									AND r.user_type = 1 
									LIMIT 5
									) o
									LEFT JOIN live.db_live l ON o.anchor_id = l.anchorid 
								GROUP BY 
									l.anchorid
								ORDER BY
									l.hot DESC`,
			util.QuerySlice2Str(matchIds))).
		Find(&anchorBaseList).
		Error
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return anchorBaseList, nil
}

func GetAnchorReservationNew(matchIds []int) ([]*api_models.GetAnchorReservation, error) {
	//FIXME  GROUP_CONCAT(anchor_id )anchor_id 使用GROUP_CONCAT 需要用GROUP BY match_id
	anchorBaseList := make([]*api_models.GetAnchorReservation, 0)
	db := global2.GetR()
	var err = db.
		Raw(fmt.Sprintf(`select match_id,anchor_id,anchor_avatar from (SELECT
										r.match_id AS match_id,
										r.user_id AS anchor_id,
										u.avatar AS anchor_avatar,
										l.hot,
										ROW_NUMBER() over ( PARTITION BY r.match_id ORDER BY l.hot desc) AS rnum
									FROM main.db_user_reservation r 
									left join main.db_user u on r.user_id=u.id 
									left join live.db_live l on r.user_id=l.anchorid
									WHERE r.match_id in (%s) AND r.user_type = 1)tb1 where tb1.rnum<=5`,
			util.QuerySlice2Str(matchIds))).
		Find(&anchorBaseList).
		Error
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert2(), err.Error())
	}
	return anchorBaseList, nil
}

func InsertUserMatchReservation(matchId int, uid, isAnchor, liveTime int) (bool, error) {
	err := mysql.GetXTable(new(db_main2.UserReservation)).
		Create(&db_main2.UserReservation{
			UserID:    uid,
			UserType:  isAnchor,
			MatchID:   matchId,
			LiveTime:  int64(liveTime),
			CreatedAt: time.Now().Unix(),
		}).Error
	if err != nil {
		if strings.Contains(err.Error(), "Duplicate") {
			return false, errors.New("已预约过")
		}
		return false, err
	}
	return true, nil
}

func DeleteUserMatchReservation(matchId int, uid int) bool {
	userReservation := &db_main2.UserReservation{}
	num := mysql.GetXTable(&db_main2.UserReservation{}).Where("match_id =? AND user_id =? ", matchId, uid).Delete(userReservation).RowsAffected
	if num < 1 {
		return false
	}
	return true
}

/*func GetReservedMatch4Crawler(uid int) ([]*models.MatchTempSchedule, error) {
	fName := "GetReservedMatch4Crawler"
	var o []*models.MatchTempSchedule
	err := getRTable(models.UserReservation{}).
		Raw("SELECT * FROM main.db_user_reservation u "+
			"LEFT JOIN models_sports.db_matches_schedule m"+
			" ON  u.match_id= m.match_id "+
			"WHERE u.user_id=?"+
			" ORDER BY u.created_at DESC", uid).
		Find(&o).Error
	if err != nil {
		return nil, fmt.Errorf("%s%s", common.Convert(fName), err.Error())
	}
	return o, err
}*/

func GetReservedMatch4Crawler(uid int) ([]*models_sports.MatchTempSchedule, error) {
	fName := "GetReservedMatch4Crawler"
	var o []*models_sports.MatchTempSchedule
	err := mysql.GetXTable(db_main2.UserReservation{}).
		Select("db_user_reservation.match_id").
		//Joins("LEFT JOIN models_sports.db_matches_schedule tb1 ON db_matches_schedule.match_id = db_user_reservation.match_id ").
		Where("user_id", uid).
		Order("created_at DESC").
		Find(&o).Error
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return o, err
}

func GetReservedMatchIds(uid uint) ([]uint, error) {
	fName := "GetReservedMatchIds"
	var ids []uint
	err := mysql.GetRTable(&db_main2.UserReservation{}).
		Where("user_id", uid).
		Pluck("match_id", &ids).
		Error
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return ids, nil
}

func GetSportMatchAttent(uid int) ([]*models_sports.SportMatchAttent, error) {
	fName := "GetSportMatchAttent"
	o := make([]*models_sports.SportMatchAttent, 0)
	whereCol := fmt.Sprintf(" uid = %d ", uid)
	err := global2.GetR().Raw(fmt.Sprintf(`
    select *,'football' as sport_type from db_football_match_attent
    where %s
    union all
    select *,'basket' as sport_type from db_basket_match_attent
    where %s
    union all
    select *,'tennis' as sport_type from db_tennis_match_attent
    where %s
`, whereCol, whereCol, whereCol)).Find(&o).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		err = nil
	}
	if err != nil {
		err = fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return o, err
}

// 该位置显示15场比赛，只显示当日正在直播和还未开始的比赛
// 如果后台配置 没有数据或数据不足15条剩余位置则默认展示以下联赛内容比赛西甲、英超、意甲、德甲、法甲+NBA+中超+CBA的比赛
// 固定时区北京时间
//`select id, competition_id, season_id, status, timehelper, home_id, home_score, away_id, away_score, 'basket' as sport_type from db_basket_match where id in (select matchid from db_basket_match_rec) and timehelper>=? and timehelper <=? and status<10 and status<>0
//	union select id, competition_id, season_id, status, timehelper, home_id, home_score, away_id, away_score, 'football' as sport_type from db_football_match where id in (select matchid from db_football_match_rec) and timehelper>=? and timehelper <=? and status<8 and status<>0
//	union (select id, competition_id, season_id, status, timehelper, home_id, home_score, away_id, away_score, 'basket' as sport_type from db_basket_match where timehelper>=? and timehelper <=? and status<10 and status<>0)
//	union (select id, competition_id, season_id, status, timehelper, home_id, home_score, away_id, away_score, 'football' as sport_type from db_football_match where timehelper>=? and timehelper <=?  and status<8 and status<>0)
//	order by timehelper asc limit 15

//func GetHotMatchCards() ([]*api_models.MatchCard, error) {
//	fName := "GetHotMatchCards"
//	var err error
//	o := make([]*api_models.MatchCard, 0)
//
//	// check redis cache
//	cacheData, err := global2.GetRds().Get(fmt.Sprintf(_const.REDIS_HOME_CACHE, "cards")).Result()
//	json.Unmarshal([]byte(cacheData), &o)
//
//	if cacheData != "" && err == nil {
//		for index, v := range o {
//			matchTime := time.Unix(int64(v.Time), 0)
//			if matchTime.Format("2006-01-02") == time.Now().Format("2006-01-02") {
//				homeScore, awayScore := getScoreINRedis(int64(v.ID), v.SportType)
//				o[index].HomeScore, o[index].AwayScore = homeScore, awayScore
//			}
//		}
//		return o, err
//	}
//
//	_, end := time2.INaDay2Unix("")
//
//	// 暂定起步时间改为3小时前
//	t, _ := time.ParseDuration("-3h")
//	start := time.Now().Add(t).Unix()
//
//	err = global2.GetR().Raw(
//		`select id, competition_id, season_id, status, timehelper, home_id, home_score, away_id, away_score, 'basket' as sport_type from db_basket_match where timehelper>=? and timehelper <=? and status<10 and status<>0
//		union select id, competition_id, season_id, status, timehelper, home_id, home_score, away_id, away_score, 'football' as sport_type from db_football_match where timehelper>=? and timehelper <=?  and status<8 and status<>0
//		order by timehelper asc limit 15
//		`, start, end, start, end, start, end, start, end).Find(&o).Error
//	if errors.Is(err, gorm.ErrRecordNotFound) {
//		err = nil
//	}
//	if err != nil {
//		return nil, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
//	}
//
//	//result cache to redis 20s
//	//ret, err := MatchDetail(o)
//	//retToString, _ := json.Marshal(ret)
//
//	//models.GetRds().Set(fmt.Sprintf(util.REDIS_HOME_CACHE, "cards"), retToString, 20*timehelper.Second)
//
//	return []*api_models.MatchCard{}, err
//}

// 有官方版权直播源赛事
func GetMatchsInfoHasStream(id int) (*models_sports.BaseMatches, error) {
	baseMatches := new(models_sports.BaseMatches)
	table := global2.Sport().Model(&models_sports.MatchTempSchedule{})
	err := table.Where("match_id = ?", id).Scan(&baseMatches).Error
	return baseMatches, err
}

// Redis 时实比分
func getScoreINRedis(id int64, sportType string) (homeScore int, awayScore int) {
	idKey := strconv.FormatInt(id, 10)
	if sportType == "basket" {
		sportType = "basketball"
	}
	score, _ := global2.GetRds().HGetAll("sport_" + sportType + "_match:" + idKey).Result()
	hs, _ := strconv.Atoi(score["HomeScore"])
	as, _ := strconv.Atoi(score["AwayScore"])
	return hs, as
}

// 获取当前体育赛事开播
func SportLiveMatchComp(sport_id uint8) (*protobuf2.SportLiveMatchCompResp, error) {
	begin, end := time2.INaDay2Unix("")
	var resp []*protobuf2.SportLiveMatchComp

	var temResp []*models_sports.LeagueName
	db := global2.Sport().Model(&models_sports.MatchTempSchedule{}).Where("match_status in (1,2) and match_time >=? AND match_time<=?", begin, end+60*60*24)
	//fixme
	if sport_id == 3 {
		db.Where("sport_id in(101,102,103,106)")
	} else {
		db.Where("sport_id", sport_id)
	}
	var err error
	err = db.Group("comp").
		Order("match_status asc").
		Find(&temResp).Error

	if err != nil {
		return nil, err
	}
	for _, v := range temResp {
		if global2.Lang.GetLang() != _const.LangChinese {
			v.Comp = v.CompShortEn
		}
		resp = append(resp, &protobuf2.SportLiveMatchComp{
			Comp: v.Comp,
		})
	}
	return &protobuf2.SportLiveMatchCompResp{
		SportLiveMatchComp: resp,
	}, nil
}

// 获取当前体育赛事开播
func SportLiveMatch(sport_id uint8, comp string) (*protobuf2.SportLiveMatchResp, error) {
	begin, end := time2.INaDay2Unix("")
	var resp []*protobuf2.SportLiveMatch
	var tmpResp []*models_sports.MatchTempSchedule
	db := global2.Sport().Model(&models_sports.MatchTempSchedule{}).
		Where("match_status in (1,2) and match_time >=? AND match_time<=?", begin, end+60*60*24)
	if global2.Lang.GetLang() == _const.LangChinese {
		db.Where("comp", comp)
	} else {
		db.Where("comp_short_en", comp)
	}
	if sport_id == 3 {
		db.Where("sport_id in(101,102,103,106)")
	} else {
		db.Where("sport_id", sport_id)
	}
	err := db.Order("match_status asc").
		Find(&tmpResp).
		Error
	if err != nil {
		return nil, err
	}
	for _, v := range tmpResp {
		if global2.Lang.GetLang() != _const.LangChinese {
			v.Away = v.AwayEn
			v.Home = v.HomeEn
			v.Comp = v.CompShortEn
			v.MatchDetailStatus = util.GetMatchStatusCodeEn(v.SportId, v.RawMatchStatus)
		}
	}
	copier.Copy(&resp, &tmpResp)
	return &protobuf2.SportLiveMatchResp{
		SportLiveMatch: resp,
	}, nil
}

func GetMatchTempScheduleInfo(matchId int) (*models_sports.MatchTempSchedule, error) {
	var matchData *models_sports.MatchTempSchedule
	err := mysql.GetSportsTable(models_sports.MatchTempSchedule{}).Where("match_id=? and sport_id in(1,2)", matchId).Order("match_time desc").First(&matchData).Error
	if err != nil {
		return nil, err
	}
	return matchData, nil
}

func GetMatchTempScheduleByIds(matchIds []int) ([]*models_sports.MatchTempSchedule, error) {
	var matchData []*models_sports.MatchTempSchedule
	err := mysql.GetSportsTable(models_sports.MatchTempSchedule{}).Where("match_id in ?", matchIds).Find(&matchData).Error
	if err != nil {
		return nil, err
	}
	return matchData, nil
}

/**  待优化
 * @Author admin  赛事需求 https://581hgf.axshare.com/#id=orzptw&p=%E8%B5%9B%E4%BA%8B%E8%AE%BE%E7%BD%AE&g=1
 * @Description //获取赛事列表列表(移动端)
 * @version: v1.8.0
 * @Date 17:50 2022/7/16
 * @Param
 * @return
 **/
func GetCompMenuList(conditionCombine string) ([]*protobuf2.CompMenu, error) {
	compMenuList := make([]*protobuf2.CompMenu, 0)

	var err error
	err = global2.Sport().Raw(
		fmt.Sprintf(`SELECT comp,comp_short_en,if(comp_short_zh is null || comp_short_zh='',comp, comp_short_zh) comp_short_zh,count(1) quantity FROM db_matches_schedule where %s GROUP BY comp`, conditionCombine)).Find(&compMenuList).Error

	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert2(), err.Error())
	}
	return compMenuList, nil
}

/**
 * @Author admin
 * @Description //获取比赛列表(移动端)
 * @version: v1.8.0
 * @Date 14:06 2022/7/18
 * @Param
 * @return
 **/
func GetMatchList(conditionCombine string, req *protobuf2.GetMatchListReq) ([]*models_sports.Match, error) {
	matchList := make([]*models_sports.Match, 0)
	sql := _const.EMPTY_STR
	if req.UserId > 0 {
		sql = fmt.Sprintf("select t1.id,t1.match_id,t1.match_time,t1.sport_id,t1.comp,if(t1.comp_short_zh is null || t1.comp_short_zh='',t1.comp, t1.comp_short_zh) comp_short_zh,"+
			"t1.comp_logo,t1.home,t1.home_logo,t1.away,t1.away_logo,t1.home_score,t1.away_score, t1.time_played,t1.match_status,t1.match_detail_status,t1.flag,t1.raw_match_status,IFNULL(t2.favorite,0) favorite,t1.comp_short_en,t1.home_en,t1.away_en,"+
			"IFNULL(t3.favorite_quantity,0) favorite_quantity from db_matches_schedule t1 left join(select match_id, 1 favorite,user_id,sport_id, null as anchor from  db_match_favorite where user_id=%d)t2 on t1.match_id=t2.match_id and t1.sport_id = t2.sport_id  left JOIN "+
			"db_match_favorite_statistics t3 on t1.match_id=t3.match_id where %s LIMIT ? OFFSET ?", req.UserId, conditionCombine)
	} else {
		sql = fmt.Sprintf("select t1.id,t1.match_id,t1.match_time,t1.sport_id,t1.comp,if(t1.comp_short_zh is null || t1.comp_short_zh='',t1.comp, t1.comp_short_zh) comp_short_zh,"+
			"t1.comp_logo,t1.home,t1.home_logo,t1.away,t1.away_logo,t1.home_score,t1.away_score,t1.time_played,t1.match_status,t1.match_detail_status,t1.flag,t1.raw_match_status,0 favorite,t1.comp_short_en,t1.home_en,t1.away_en,"+
			"IFNULL(t3.favorite_quantity,0) favorite_quantity, null as anchor from db_matches_schedule t1 left JOIN db_match_favorite_statistics t3 on t1.match_id=t3.match_id where %s LIMIT ? OFFSET ?", conditionCombine)
	}
	if err := global2.Sport().Raw(sql, req.Size, (req.Page-1)*req.Size).Find(&matchList).Error; err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert2(), err.Error())
	}

	// find out anchor reservation
	var ids []int32
	for _, v := range matchList {
		ids = append(ids, v.MatchId)
	}
	var reserv []*models_sports.ReservationAnchor
	if err := global2.GetR().Table("main.db_user_reservation").Where("match_id in (?)", ids).Scan(&reserv).Error; err != nil {
		return nil, err
	}
	for idx, v := range matchList {
		for _, r := range reserv {
			if v.MatchId == r.MatchId {
				matchList[idx].ReservationAnchor = append(matchList[idx].ReservationAnchor, r)
			}
		}
	}

	return matchList, nil
}

/**
 * @Author
 * @Description //TODO
 * @Date 17:39 2022/8/29
 * @Param
 * @return
 **/
func GetMatchListCount(conditionCombine string) int64 {
	sql := _const.EMPTY_STR
	var count int64
	sql = fmt.Sprintf("select count(1) counts from db_matches_schedule t1  where %s ", conditionCombine)
	global2.Sport().Raw(sql).Scan(&count)
	return count
}

/**
 * @Author admin
 * @Description //
 * @Date 11:25 2022/10/18
 * @Param
 * @return
 **/
func GetMatchListCountOfDays(conditionCombine string) map[string]int32 {
	sql := _const.EMPTY_STR
	var rows []map[string]interface{}
	results := make(map[string]int32)
	sql = fmt.Sprintf("select count(1) counts,date_format(FROM_UNIXTIME(match_time),'%%Y-%%m-%%d') date from db_matches_schedule t1  where %s  group by date_format(FROM_UNIXTIME(match_time),'%%Y-%%m-%%d')", conditionCombine)
	global2.Sport().Raw(sql).Find(&rows)
	for _, row := range rows {
		results[cast.ToString(row["date"])] = cast.ToInt32(row["counts"])
	}
	return results
}

func GetMatchLive(matchIds []interface{}, anchorNum int) []*api_models.GetAnchorReservations {
	anchorBaseList := make([]*api_models.GetAnchorReservations, 0)
	global2.Live().Raw(fmt.Sprintf("select match_id,GROUP_CONCAT(anchor_id) anchor_ids,GROUP_CONCAT(anchor_avatar) anchor_avatars from (SELECT l.matchid AS match_id,l.anchorid AS anchor_id, l.anchor_avatar,ROW_NUMBER() over ( PARTITION BY l.matchid ORDER BY l.hot desc) AS rnum FROM db_live l WHERE matchid in (%s))tb1 where tb1.rnum<=%d group by match_id",
		util.QueryInterfaceSlice2Str(matchIds), anchorNum)).Find(&anchorBaseList)
	return anchorBaseList
}

func InsertFavorite(session *gorm.DB, matchFavorite *models_sports.MatchFavorite) int64 {
	return session.Model(&models_sports.MatchFavorite{}).Create(matchFavorite).RowsAffected
}

func DelFavorite(session *gorm.DB, params *protobuf2.FavoriteReq) int64 {
	return session.Where("match_id=? and user_id=?", params.MatchId, params.UserId).Delete(&models_sports.MatchFavorite{}).RowsAffected
}

func FavoriteStatistics(session *gorm.DB, matchId, statistics int) int64 {
	return session.Exec(`INSERT INTO db_match_favorite_statistics (match_id,favorite_quantity) VALUES (?,1) ON DUPLICATE KEY UPDATE favorite_quantity=favorite_quantity+?`, matchId, statistics).RowsAffected
}

func CountMatch(matchId, sportId int32) (*models_sports.MatchTempSchedule, error) {
	match := &models_sports.MatchTempSchedule{}
	err := mysql.GetSportsTable(&models_sports.MatchTempSchedule{}).Where("match_id=?", matchId).Find(&match).Error
	return match, err
}

func CountUserFavorite(UserId, sportId int) int64 {
	var count int64
	if sportId == 999 {
		//getSportsTable(&models.MatchFavorite{}).
		//	Joins("inner join db_matches_schedule on db_match_favorite.match_id=db_matches_schedule.match_id").
		//	Where("db_match_favorite.user_id=? and db_matches_schedule.focus=2", UserId).Count(&count)
		mysql.GetSportsTable(&models_sports.MatchFavorite{}).Where("user_id=?", UserId).Count(&count)
	} else {
		mysql.GetSportsTable(&models_sports.MatchFavorite{}).
			Joins("inner join db_matches_schedule on db_match_favorite.match_id=db_matches_schedule.match_id").
			Where("db_match_favorite.user_id=? and db_match_favorite.sport_id=?", UserId, sportId).Count(&count)
	}
	return count
}

func GetFavoriteQuantityByMatch(matchId int) int {
	var favoriteQuantity int
	mysql.GetSportsTable(&models_sports.MatchFavoriteStatistics{}).Where("match_id=?", matchId).Pluck("favorite_quantity", &favoriteQuantity)
	return favoriteQuantity
}

func GetMatchById(matchId int) (match *protobuf2.Match) {
	match = &protobuf2.Match{}
	global2.Sport().Raw("select * from db_matches_schedule where match_id=? order by match_time desc limit 1", matchId).Scan(match)
	return match
}

func GetMatchTime(matchIds []interface{}) ([]*protobuf2.MatchScore, error) {
	var matchData []*protobuf2.MatchScore
	err := mysql.GetSportsTable(models_sports.MatchTempSchedule{}).Where("match_id in ?", matchIds).Find(&matchData).Error
	if err != nil {
		return nil, err
	}
	return matchData, nil
}

// 1.足球  2.篮球
func GetMatchSportId(matchId int) int {
	if matchId < 1 {
		return 0
	}
	match := GetMatchById(matchId)
	if match == nil {
		return 0
	}
	return int(match.SportId)
}
